package com.xuwei.base.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;

//内省:操作属性的（类中的getter和setter方法）
public class Demo1 {
	//属性名称：getClass,他的属性名称class
	//getAbc --->abc
	@Test
	public void test1() throws Exception{
		//得到Student类中的属性，被封装到了BeanInfo中
		BeanInfo bi = Introspector.getBeanInfo(Student.class);
		//得到类中的所有的属性描述器
		PropertyDescriptor[] pds = bi.getPropertyDescriptors();
		System.out.println(pds.length);
		for(PropertyDescriptor pd:pds){
			System.out.println(pd.getName());
		}
	}
	@Test
	public void test2() throws Exception{
		Student s = new Student();
//		Class clazz = Class.forName("com.xuwei.base.introspector.Student");
//		Student s = (Student)clazz.newInstance();
		PropertyDescriptor pd = new PropertyDescriptor("name", Student.class);
		Method m = pd.getReadMethod();//得到getName()方法
		String value = (String)m.invoke(s, null);
		System.out.println(value);
		//改变name的值
		Method m1 = pd.getWriteMethod();//得到setName()方法
		m1.invoke(s, "Ben");
		System.out.println(s.getName());
	}
	//利用BeanUtils框架操作属性:实现原理类似test2
	@Test
	public void test3() throws Exception{
		Student s = new Student();
		//为什么要返回字符串：用户的所有输入都是字符串
		String str = BeanUtils.getProperty(s, "name");//调用getName方法
		System.out.println(str);
		//设置值
		BeanUtils.setProperty(s, "name", "Ben");
		System.out.println(s.getName());
	}
	@Test//BeanUtils可以进行类型的自动转换，但仅限基本类型：本来需要int型，给个字符串，ok
	public void test4() throws Exception{
		Student s = new Student();
		String str = BeanUtils.getProperty(s, "age");
		System.out.println(str);
		BeanUtils.setProperty(s, "age", "26");
		System.out.println(s.getAge());
	}
	//非基本类型的属性设置
	
	//用户的输入都是String
	//String <----->其他类型间的互相转换
	//用户看到的结果都是String
	@Test
	public void test5() throws Exception{
		Student s = new Student();
		//给BeanUtils注册类型转换器：自定义的转换器
		ConvertUtils.register(new Converter() {
			//type:目标类型
			//value:当前传入的值
			public Object convert(Class type, Object value) {
//				if(type.equals(Date.class)){
//					//字符串转换为Date
//				}else{
//					//Date转换为字符串
//				}
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
				if(value instanceof String){
					//字符串转换为Date
					String v = (String)value;
					Date d;
					try {
						d = df.parse(v);
					} catch (ParseException e) {
						throw new RuntimeException(e);
					}
					return d;
				}else{
					//Date转换为字符串
					Date d = (Date)value;
					return df.format(d);
				}
				
			}
		}, Date.class);
		BeanUtils.setProperty(s, "birthday", "1989-10-09");
		System.out.println(s.getBirthday());
	}
	@Test//转换器原理参考test5
	public void test51() throws Exception{
		Student s = new Student();
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		BeanUtils.setProperty(s, "birthday", "1999-10-09");
		System.out.println(s.getBirthday());
	}
	@Test//转换器原理参考test5
	public void test6() throws Exception{
		Student s = new Student();
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		BeanUtils.setProperty(s, "birthday", "1999-10-09");
		System.out.println(s.getBirthday());
	}
}
